package com.lvyq.javaprint.service;

import cn.hutool.json.JSONUtil;
import com.lvyq.javaprint.common.GlobalCode;
import com.lvyq.javaprint.model.PrintData;
import com.lvyq.javaprint.util.PDFPrintUtils;
import com.lvyq.javaprint.util.PrintUtils;
import com.lvyq.javaprint.ws.WebSocketServer;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.PDFPageable;
import org.apache.pdfbox.printing.PDFPrintable;
import org.apache.pdfbox.printing.Scaling;
import org.springframework.web.multipart.MultipartFile;
import javax.print.PrintServiceLookup;
import javax.print.attribute.PrintRequestAttributeSet;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author lvyq pdf打印服务
 * @version 1.0
 * Create by 2024-08-06 15:07
 */
public class PDFPrintService implements PrintService {

    private final ExecutorService executorService = Executors.newFixedThreadPool(10); // 创建线程池


    @Override
    public void print(String text, PrintData data) {
        throw  new UnsupportedOperationException("PDFPrintService 打印服务不支持文本打印");
    }

    @Override
    public void print(InputStream inputStream, PrintData data) {

    }

    @Override
    public void print(MultipartFile multipartFile, PrintData data) {
        PDDocument document  = PDFPrintUtils.getPDDocument(multipartFile);
        asyncPrint(document,data);
    }


    @Override
    public void print(File file, PrintData data) {
        PDDocument document =PDFPrintUtils.getPDDocument(file);
        asyncPrint(document,data);
    }

    @Override
    public void print(URL url, PrintData data) {
        PDDocument document = PDFPrintUtils.getPDDocument(url);
        asyncPrint(document,data);
    }

    /**
     * @description 关闭文档
     * @author lvyq
     * @param[1] document
     * @throws
     * @time 2024-08-07 17:22
     */
    private void closeDocument(PDDocument document) {
        // 确保PDF文档被正确关闭以释放资源
        if (document != null) {
            try {
                document.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @description 异步线程打印
     * @author lvyq
     * @param[1] document
     * @param[2] data
     * @throws
     * @time 2024-08-08 15:32
     */
    private void asyncPrint(PDDocument document,PrintData data){
        // 创建打印请求属性集合
        PrintRequestAttributeSet attributes = PrintUtils.handleAttributeWithPrintData(data);
        executorService.submit(() -> {
            try {
                PrinterJob job = PrinterJob.getPrinterJob();

                // 使用默认打印机
                job.setPrintService(PrintServiceLookup.lookupDefaultPrintService());
                // 设置打印参数
               // job.setPageable(new PDFPageable(document));

                //解决在pdf中透明图片（水印图）与文本重叠时,打印出的文字失真问题
                PDFPrintable pdfPrintable = new PDFPrintable(document, Scaling.ACTUAL_SIZE);
                job.setPrintable(pdfPrintable);

                WebSocketServer.SendMessageById(JSONUtil.toJsonStr(GlobalCode.PRINT_BEFORE),data.getSessionId());
                job.print(attributes);
                WebSocketServer.SendMessageById(JSONUtil.toJsonStr(GlobalCode.PRINT_START),data.getSessionId());
            } catch ( Exception e) {
                WebSocketServer.SendMessageById(JSONUtil.toJsonStr(GlobalCode.PRINT_EXCEPTION),data.getSessionId());
            } finally {
                closeDocument(document);
            }
        });
    }


}
